#ifndef SEGMENTS_H
#define SEGMENTS_H

/* 
 * This file contains definitions and macros for dealing with segments
 * and GDT entries.
 * 
 * The Globa Descriptor Table (GDT) is a table in memory that defines
 * the behaviour of segment registers. Each segment register must point
 * to an entry in the GDT. The entry defines the location in memory
 * and properties of a particular memory segment.
 * 
 * Entries in the GDT are 8 byte numbers that contain:
 * 
 *   | Bytes |               Meaning                  |
 *   --------------------------------------------------
 *   |  16   | Low bits of upper segment limit        |
 *   |  16   | Low bits of segment base address       |
 *   |   8   | Middle bits of segment base address    |
 *   |   4   | Segment type                           |
 *   |   1   | 0 = system, 1 = application            |
 *   |   2   | Privilege level                        |
 *   |   1   | Present                                |
 *   |   4   | High bits of upper segment limit       |
 *   |   1   | Unused                                 |
 *   |   1   | Reserved                               |
 *   |   1   | 0 = 16-bit segment, 1 = 32-bit segment |
 *   |   1   | Multiply limit by 4K, 1-yes, 0-no      |
 *   |   8   | High bits of segment base address      |
 */


#define SEG_NULL	\
	.word	0, 0;	\
	.byte	0, 0, 0, 0	

#define SEG(type, base, limit)	\
	.word	( ((limit)>>12) & 0xffff );	\
	.word	( (base) & 0xffff );	\
	.byte	( ((base)>>16) & 0xff );	\
	.byte	( ((type) & 0xf) | 0x90 );	\
	.byte	( (((limit)>>28) & 0xf) | 0xC0 );	\
	.byte	( ((base)>>24) & 0xff )

// Application segment type bits
#define STA_X		0x8	    // Executable segment
#define STA_E		0x4	    // Expand down (non-executable segments)
#define STA_C		0x4	    // Conforming code segment (executable only)
#define STA_W		0x2	    // Writeable (non-executable segments)
#define STA_R		0x2	    // Readable (executable segments)
#define STA_A		0x1	    // Accessed

#endif	// SEGMENTS_H
